package coins;

//~--- non-JDK imports --------------------------------------------------------

import com.dukascopy.api.IEngine.OrderCommand;
import com.dukascopy.api.IMessage;
import com.dukascopy.api.IOrder;
import com.dukascopy.api.ITick;
import com.dukascopy.api.Instrument;
import com.dukascopy.api.JFException;
import com.dukascopy.api.OfferSide;

//~--- JDK imports ------------------------------------------------------------

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Order implements IOrder {
    private double       amount;
    private double       closePrice;
    private long         closeTime;
    private long         creationTime;
    private String       label;
    private double       openPrice;
    private OrderCommand orderCommand;
    private State        state;

    public Order(Instrument instrument, OrderCommand orderCommand, double amount, String label, State state) {
        this.amount       = amount;
        this.orderCommand = orderCommand;
        this.label        = label;
        this.state        = state;
    }

    @Override
    public void close() throws JFException {
        state = State.CLOSED;
    }

    @Override
    public void close(double amount) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void close(double amount, double price) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void close(double amount, double price, double slippage) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public double getAmount() {
        return amount;
    }

    @Override
    public double getClosePrice() {
        return closePrice;
    }

    @Override
    public long getCloseTime() {
        return closeTime;
    }

    @Override
    public String getComment() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public long getCreationTime() {
        return creationTime;
    }

    @Override
    public long getFillTime() {
        return getCreationTime();
    }

    @Override
    public long getGoodTillTime() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public String getId() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public Instrument getInstrument() {
        return Instrument.EURUSD;
    }

    @Override
    public String getLabel() {
        return label;
    }

    @Override
    public double getOpenPrice() {
        return openPrice;
    }

    @Override
    public OrderCommand getOrderCommand() {
        return orderCommand;
    }

    @Override
    public double getProfitLossInAccountCurrency() {

        // TODO: By us
        return 0;
    }

    @Override
    public double getProfitLossInPips() {
        double pips;

        if (orderCommand == OrderCommand.BUY) {
            pips = closePrice - openPrice;
        } else {
            pips = openPrice - closePrice;
        }

        return (pips * 10000);
    }

    @Override
    public double getProfitLossInUSD() {
        double pips = getProfitLossInPips();

        // Profit calculation.
        // If orderAmount is 10000 EUR, profit to pips ratio is 1:1
        // NOTE: amount is in millions. Normailize it to 10000 i.e the value of pips
        return (pips * amount / 0.01);
    }

    @Override
    public double getRequestedAmount() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public State getState() {
        return state;
    }

    @Override
    public double getStopLossPrice() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public OfferSide getStopLossSide() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public double getTakeProfitPrice() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public double getTrailingStep() {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public boolean isLong() {
        return orderCommand == OrderCommand.BUY;
    }

    @Override
    public void setGoodTillTime(long goodTillTime) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void setOpenPrice(double price) throws JFException {
        openPrice = price;
    }

    @Override
    public void setRequestedAmount(double amount) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void setStopLossPrice(double price) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void setStopLossPrice(double price, OfferSide side) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void setStopLossPrice(double price, OfferSide side, double trailingStep) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void setTakeProfitPrice(double price) throws JFException {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public void waitForUpdate(long timeoutMills) {
        throw new RuntimeException("Not implemented");
    }

    @Override
    public IMessage waitForUpdate(long timeout, TimeUnit unit) {
        throw new RuntimeException("Not implemented");
    }

    public void setCloseTick(ITick tick) {
        closePrice = (getOrderCommand() == OrderCommand.BUY)
                     ? tick.getBid()
                     : tick.getAsk();
    }

    public void setOpenTick(ITick tick) {
        openPrice = (getOrderCommand() == OrderCommand.BUY)
                    ? tick.getAsk()
                    : tick.getBid();
    }

    @Override
    public String toString() {
        SimpleDateFormat dateFormat    = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        StringBuilder    stringBuilder = new StringBuilder();

        stringBuilder.append("Order [");
        stringBuilder.append(getLabel());
        stringBuilder.append(", ");
        stringBuilder.append(getAmount());
        stringBuilder.append(", ");
        stringBuilder.append(getOrderCommand());
        stringBuilder.append(", ");
        stringBuilder.append(getOpenPrice());
        stringBuilder.append(", ");
        stringBuilder.append(getClosePrice());
        stringBuilder.append(", ");
        stringBuilder.append(dateFormat.format(new Date(getFillTime() - (long) (5.5 * 60 * 60 * 1000))));
        stringBuilder.append(", ");
        stringBuilder.append(dateFormat.format(new Date(getCloseTime() - (long) (5.5 * 60 * 60 * 1000))));
        stringBuilder.append(", ");
        stringBuilder.append(getState());
        stringBuilder.append(", ");
        stringBuilder.append(getProfitLossInUSD());
        stringBuilder.append("]");

        return stringBuilder.toString();
    }

    public void setCreationTime(long time) {
        creationTime = time;
    }

    public void setCloseTime(long time) {
        closeTime = time;
    }
}


//~ Formatted by Jindent --- http://www.jindent.com
